package com.stu.javabase;

/**
 * Java基础数据类型和比较操作演示
 * 涵盖：
 * - JDK与JRE的区别
 * - Java基本数据类型
 * - == 和 equals 的区别
 * - 访问修饰符的区别
 * 
 * @author 学习者
 * @version 1.0
 */
public class DataTypesAndComparison {
    
    public static void main(String[] args) {
        System.out.println("=== Java基础数据类型和比较操作演示 ===");
        
        // 1. Java基本数据类型演示
        demonstrateBasicDataTypes();
        
        // 2. == 和 equals 比较演示
        demonstrateEqualsComparison();
        
        // 3. 访问修饰符演示
        demonstrateAccessModifiers();
        
        // 4. 数值计算和类型转换演示
        demonstrateTypeConversion();
    }
    
    /**
     * 演示Java的8种基本数据类型
     * byte、short、int、long、float、double、char、boolean
     */
    private static void demonstrateBasicDataTypes() {
        System.out.println("\n=== Java基本数据类型演示 ===");
        
        // 整数类型
        byte byteValue = 127; // 8位，范围：-128 ~ 127
        short shortValue = 32767; // 16位，范围：-32768 ~ 32767
        int intValue = 2147483647; // 32位，范围：-2^31 ~ 2^31-1
        long longValue = 9223372036854775807L; // 64位，范围：-2^63 ~ 2^63-1
        
        // 浮点类型
        float floatValue = 3.14f; // 32位单精度
        double doubleValue = 3.141592653589793; // 64位双精度
        
        // 字符类型
        char charValue = '中'; // 16位Unicode字符
        
        // 布尔类型
        boolean booleanValue = true; // true或false
        
        System.out.println("byte值：" + byteValue + "，大小：" + Byte.BYTES + "字节");
        System.out.println("short值：" + shortValue + "，大小：" + Short.BYTES + "字节");
        System.out.println("int值：" + intValue + "，大小：" + Integer.BYTES + "字节");
        System.out.println("long值：" + longValue + "，大小：" + Long.BYTES + "字节");
        System.out.println("float值：" + floatValue + "，大小：" + Float.BYTES + "字节");
        System.out.println("double值：" + doubleValue + "，大小：" + Double.BYTES + "字节");
        System.out.println("char值：" + charValue + "，大小：" + Character.BYTES + "字节");
        System.out.println("boolean值：" + booleanValue);
        
        // byte取值范围演示
        System.out.println("\nbyte取值范围：" + Byte.MIN_VALUE + " ~ " + Byte.MAX_VALUE);
        System.out.println("为什么是-128~127？因为byte是8位，2^8=256个数，包含0，所以是-128~127");
    }
    
    /**
     * 演示 == 和 equals 的区别
     * == 比较的是引用地址（基本类型比较值）
     * equals 比较的是对象内容
     */
    private static void demonstrateEqualsComparison() {
        System.out.println("\n=== == 和 equals 比较演示 ===");
        
        // 基本数据类型比较
        int a = 100;
        int b = 100;
        System.out.println("基本类型 int a=100, b=100:");
        System.out.println("a == b: " + (a == b)); // true，比较值
        
        // String比较
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = new String("Hello");
        
        System.out.println("\nString比较:");
        System.out.println("str1 == str2: " + (str1 == str2)); // true，字符串常量池
        System.out.println("str1 == str3: " + (str1 == str3)); // false，不同对象
        System.out.println("str1.equals(str3): " + str1.equals(str3)); // true，内容相同
        
        // Integer包装类比较
        Integer int1 = 100;
        Integer int2 = 100;
        Integer int3 = new Integer(100);
        Integer int4 = 200;
        Integer int5 = 200;
        
        System.out.println("\nInteger包装类比较:");
        System.out.println("Integer int1=100, int2=100:");
        System.out.println("int1 == int2: " + (int1 == int2)); // true，缓存池(-128~127)
        System.out.println("int1 == int3: " + (int1 == int3)); // false，new创建新对象
        System.out.println("int1.equals(int3): " + int1.equals(int3)); // true，内容相同
        
        System.out.println("\nInteger int4=200, int5=200:");
        System.out.println("int4 == int5: " + (int4 == int5)); // false，超出缓存池范围
        System.out.println("int4.equals(int5): " + int4.equals(int5)); // true，内容相同
        
        // 自定义对象比较
        Person person1 = new Person("张三", 25);
        Person person2 = new Person("张三", 25);
        Person person3 = person1;
        
        System.out.println("\n自定义对象比较:");
        System.out.println("person1 == person2: " + (person1 == person2)); // false，不同对象
        System.out.println("person1 == person3: " + (person1 == person3)); // true，同一对象
        System.out.println("person1.equals(person2): " + person1.equals(person2)); // 取决于equals实现
    }
    
    /**
     * 演示访问修饰符的区别
     * public：公共的，任何地方都可以访问
     * protected：受保护的，同包或子类可以访问
     * 默认（包访问权限）：同包可以访问
     * private：私有的，只有本类可以访问
     */
    private static void demonstrateAccessModifiers() {
        System.out.println("\n=== 访问修饰符演示 ===");
        
        AccessModifierDemo demo = new AccessModifierDemo();
        
        // public成员可以访问
        System.out.println("public变量: " + demo.publicVar);
        demo.publicMethod();
        
        // protected成员可以访问（同包）
        System.out.println("protected变量: " + demo.protectedVar);
        demo.protectedMethod();
        
        // 默认访问权限可以访问（同包）
        System.out.println("默认访问权限变量: " + demo.defaultVar);
        demo.defaultMethod();
        
        // private成员不能直接访问，需要通过public方法
        // System.out.println(demo.privateVar); // 编译错误
        demo.accessPrivateVar(); // 通过public方法访问private成员
    }
    
    /**
     * 演示类型转换和数值计算
     */
    private static void demonstrateTypeConversion() {
        System.out.println("\n=== 类型转换和数值计算演示 ===");
        
        // short s1 = 1; s1 += 1; 正确
        short s1 = 1;
        s1 += 1; // 复合赋值运算符会自动进行类型转换
        System.out.println("short s1 = 1; s1 += 1; 结果: " + s1);
        
        // short s2 = 1; s2 = s2 + 1; 错误，需要强制类型转换
        short s2 = 1;
        s2 = (short)(s2 + 1); // 需要强制转换，因为s2+1结果是int类型
        System.out.println("short s2 = 1; s2 = (short)(s2 + 1); 结果: " + s2);
        
        // float n = 1.8; 错误，需要加f后缀
        // float n = 1.8; // 编译错误，1.8默认是double类型
        float n = 1.8f; // 正确
        System.out.println("float n = 1.8f; 结果: " + n);
        
        // i++ 和 ++i 的区别
        int i = 5;
        int j = 5;
        System.out.println("\ni++和++i的区别:");
        System.out.println("i的初始值: " + i);
        System.out.println("i++的返回值: " + (i++)); // 先返回值，再自增
        System.out.println("i++后i的值: " + i);
        
        System.out.println("j的初始值: " + j);
        System.out.println("++j的返回值: " + (++j)); // 先自增，再返回值
        System.out.println("++j后j的值: " + j);
        
        // 位运算优化乘法
        int num = 8;
        System.out.println("\n位运算优化乘法:");
        System.out.println("2 * 8 = " + (2 * 8));
        System.out.println("2 << 3 = " + (2 << 3)); // 左移3位相当于乘以2^3=8
        System.out.println("位运算更高效，因为直接操作二进制位");
    }
}

/**
 * 访问修饰符演示类
 */
class AccessModifierDemo {
    public String publicVar = "public变量";
    protected String protectedVar = "protected变量";
    String defaultVar = "默认访问权限变量";
    private String privateVar = "private变量";
    
    /**
     * public方法
     */
    public void publicMethod() {
        System.out.println("调用public方法");
    }
    
    /**
     * protected方法
     */
    protected void protectedMethod() {
        System.out.println("调用protected方法");
    }
    
    /**
     * 默认访问权限方法
     */
    void defaultMethod() {
        System.out.println("调用默认访问权限方法");
    }
    
    /**
     * private方法
     */
    private void privateMethod() {
        System.out.println("调用private方法");
    }
    
    /**
     * 通过public方法访问private成员
     */
    public void accessPrivateVar() {
        System.out.println("通过public方法访问private变量: " + privateVar);
        privateMethod();
    }
}

/**
 * Person类用于演示对象比较
 */
class Person {
    private String name;
    private int age;
    
    /**
     * 构造方法
     * @param name 姓名
     * @param age 年龄
     */
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    /**
     * 重写equals方法，用于内容比较
     * @param obj 比较对象
     * @return 是否相等
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && 
               (name != null ? name.equals(person.name) : person.name == null);
    }
    
    /**
     * 重写hashCode方法
     * @return 哈希码
     */
    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
    
    /**
     * 重写toString方法
     * @return 字符串表示
     */
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}